package org.clever.arkdemo.video.utils;

import org.clever.arkdemo.video.domain.dto.TencentVodUploadSignParam;
import org.clever.arkdemo.video.domain.error.SignatureException;
import org.clever.arkdemo.video.domain.vo.VideoUploadSign;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.util.Base64;

/**
 * 腾讯云点播的签名工具。
 */
public class TencentVodSignUtils {

    /// 签名算法
    public static final String HMAC_ALGORITHM = "HmacSHA1";
    /// 签名字符集
    public static final String CONTENT_CHARSET = "UTF-8";

    /**
     * 获得视频上传签名，详情请参考：<a href="https://cloud.tencent.com/document/product/266/9221">客户端上传签名</a>
     */
    public static VideoUploadSign getVideoUploadSign(TencentVodUploadSignParam param) {
        /// (必填)当前 Unix 时间戳。
        long currentTimeStamp = System.currentTimeMillis();
        /// (必填)当前时间戳加有效期。
        long expireTime = currentTimeStamp + param.getTimeout();
        /// (必填)随机数，用于生成签名。
        /// 构造签名明文串的参数。十进制数，最大值4294967295（2^32-1，即32位无符号二进制数的最大值）。
        int random = (int)(Math.random() * 100000000);
        /// (必填)云 API 密钥中的 SecretId
        String secretId = param.getSecretId();

        UrlParamMap paramMap = new UrlParamMap();
        paramMap.putNotNull("currentTimeStamp", currentTimeStamp);
        paramMap.putNotNull("expireTime", expireTime);
        paramMap.putNotNull("random", random);
        paramMap.putNotNull("secretId", secretId);
        paramMap.putNotNull("classId", param.getClassId());
        paramMap.putNotNull("procedure", param.getProcedure());
        paramMap.putNotNull("taskPriority", param.getTaskPriority());
        paramMap.putNotNull("taskNotifyMode", param.getTaskNotifyMode());
        paramMap.putNotNull("sourceContext", param.getSourceContext());
        paramMap.putNotNull("oneTimeValid", param.getOneTimeValid());
        paramMap.putNotNull("vodSubAppId", param.getVodSubAppId());
        paramMap.putNotNull("sessionContext", param.getSessionContext());
        paramMap.putNotNull("storageRegion", param.getStorageRegion());

        /// 云 API 密钥中的 SecretKey，配置位置： https://console.cloud.tencent.com/cam/capi
        String secretKey = param.getSecretKey();
        String original = paramMap.toUrlParam();
        String signature = getUploadSignature(secretKey, original);

        VideoUploadSign videoUploadSign = new VideoUploadSign();
        videoUploadSign.setSignature(signature);
        videoUploadSign.setExpireTime(expireTime);
        videoUploadSign.setCurrentTimeStamp(currentTimeStamp);
        return videoUploadSign;
    }


    public static byte[] byteMerger(byte[] byte1, byte[] byte2) {
        byte[] byte3 = new byte[byte1.length + byte2.length];
        System.arraycopy(byte1, 0, byte3, 0, byte1.length);
        System.arraycopy(byte2, 0, byte3, byte1.length, byte2.length);
        return byte3;
    }

    // 获取签名
    public static String getUploadSignature(String secretKey, String original) {
        try {
            String strSign = "";
            // 生成原始参数字符串
            Mac mac = Mac.getInstance(HMAC_ALGORITHM);
            SecretKeySpec secretKeySpec = new SecretKeySpec(secretKey.getBytes(CONTENT_CHARSET), mac.getAlgorithm());
            mac.init(secretKeySpec);
            byte[] hash = mac.doFinal(original.getBytes(CONTENT_CHARSET));
            byte[] sigBuf = byteMerger(hash, original.getBytes(CONTENT_CHARSET));
            strSign = Base64.getEncoder().encodeToString(sigBuf);
            return strSign;
        } catch (Exception e) {
            throw  new SignatureException("腾讯云视频上传签名失败！", e);
        }
    }


}
